Completed
Pull Request — master (#6)
by Janis
03:08
created

View.destroyDropdown   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 5
rs 9.4285
c 1
b 0
f 0
cc 2
nc 2
nop 0
1
/**
2
 * nextCloud - ocr
3
 *
4
 * This file is licensed under the Affero General Public License version 3 or
5
 * later. See the COPYING file.
6
 *
7
 * @author Janis Koehr <[email protected]>
8
 * @copyright Janis Koehr 2016
9
 */
10
(function() {
11
	/**
12
	 * Constructor of the View object.
13
	 * This will update the different parts of the html.
14
	 * @param ocr
15
	 * @param filehandler
16
	 * @constructor
17
	 */
18
19
	// Handlebarsjs template
20
	var TEMPLATE_OCR_DROPDOWN = '<div id="ocrDropdown" class="ocrUserInterface">'+
21
		'{{#if noMatches}}'+
22
		t('ocr', 'No languages for tesseract available')+
23
		'{{else}}'+
24
		t('ocr', 'Select')+
25
		':'+
26
		'<select id="ocrLanguage">'+
27
		'{{#each languages}}'+
28
		'<option value="{{this}}">{{this}}</option>'+
29
		'{{/each}}'+
30
		'</select>'+
31
		'<input type="button" id="processOCR" value="'+
32
		t('ocr', 'Process')+
33
		'" />'+
34
		'{{/if}}'+
35
		'</div>';
36
37
	var TEMPLATE_OCR_SELECTED_FILE_ACTION = '<span class="selectedActionsOCR hidden">'+
38
		'<a id="selectedFilesOCR" href="" class="ocr">'+
39
		'<span class="icon icon-external"></span>'+
40
		'<span>'+t('ocr', 'OCR')+'</span>'+
41
		'</a>'+
42
		'</span>';
43
44
	var View = function (ocr) {
45
		this._ocr = ocr;
46
		this._selectedFiles = [];
47
		this._row = undefined;
48
	};
49
50
	/**
51
	 * Class prototype for the View. Following functions are available:
52
	 *
53
	 */
54
	View.prototype = {
55
		initialize: function () {
56
			this.renderSelectedActionButton();
57
			this.registerFileActions();
58
			this.registerEvents();
59
			this.loopForStatus();
60
		},
61
		destroy: function () {
62
			var self = this;
63
			self.destroyDropdown();
64
			self.destroySelectedActionButton();
65
			OCA.Files.fileActions.clear();
66
			OCA.Files.fileActions.registerDefaultActions();
67
		},
68
		registerFileActions: function () {
69
			var self = this;
70
			/**
71
			 * Register FileAction for mimetype pdf
72
			 */
73
			OCA.Files.fileActions.registerAction({
74
				name: 'Ocr',
75
				displayName: t('ocr', 'OCR'),
76
				order: 100,
77
				mime: 'application/pdf',
78
				permissions: OC.PERMISSION_UPDATE,
79
				altText: t('ocr', 'OCR'),
80
				iconClass: 'icon-external',
81
				actionHandler: function (filename, context) {
82
					var path = context.dir || context.fileList.getCurrentDirectory();
83
					var mimetype = context.fileActions.getCurrentMimeType();
84
					var type = context.fileActions.getCurrentType();
85
					self.renderFileAction(filename, path, type, mimetype);
86
				}
87
			});
88
			/**
89
			 * Register FileAction for mimetype image
90
			 */
91
			OCA.Files.fileActions.registerAction({
92
				name: 'Ocr',
93
				displayName: t('ocr', 'OCR'),
94
				order: 100,
95
				mime: 'image',
96
				permissions: OC.PERMISSION_UPDATE,
97
				altText: t('ocr', 'OCR'),
98
				iconClass: 'icon-external',
99
				actionHandler: function (filename, context) {
100
					var path = context.dir || context.fileList.getCurrentDirectory();
101
					var mimetype = context.fileActions.getCurrentMimeType();
102
					var type = context.fileActions.getCurrentType();
103
					self.renderFileAction(filename, path, type, mimetype);
104
				}
105
			});
106
		},
107
		setSelectedFiles: function (selectedFiles) {
108
			var self = this;
109
			self._selectedFiles = selectedFiles;
110
		},
111
		getSelectedFiles: function () {
112
			var self = this;
113
			return self._selectedFiles;
114
		},
115
		destroySelectedActionButton: function () {
116
			// remove the Template
117
			$('.selectedActionsOCR').remove();
118
		},
119
		renderSelectedActionButton: function () {
120
			// append the TEMPLATE to correct position
121
			$(TEMPLATE_OCR_SELECTED_FILE_ACTION).appendTo($('#headerName-container'));
122
		},
123
		destroyDropdown: function () {
124
			if ($('#ocrDropdown').length){
125
				$('#ocrDropdown').detach();
126
			}
127
		},
128
		renderDropdown: function(){
129
			var self = this;
130
			self.destroyDropdown();
131
			/** global: Handlebars */
132
			var template = Handlebars.compile(TEMPLATE_OCR_DROPDOWN);
133
			var noMatches = true;
134
			var languages = self._ocr.getLanguages();
135
			if(languages.length > 0 && typeof languages !== undefined){ noMatches = false; }
136
			return template({languages: languages, noMatches: noMatches});
137
		},
138
		renderFileAction: function (file, path, type, mimetype) {
139
			var self = this;
140
			var html = self.renderDropdown();
141
			$(html).appendTo($('tr').filterAttr('data-file',file).find('td.filename'));
142
			var files = [{name: file, path: path, type: type, mimetype: mimetype}];
143
			self.setSelectedFiles(files);
144
		},
145
		toggleSelectedActionButton: function () {
146
			var self = this;
147
			var selectedActionButton = $('.selectedActionsOCR');
148
			var selFiles = OCA.Files.App.fileList.getSelectedFiles();
149
			if(selFiles.length > 0 && typeof selFiles !== undefined){
150
				//show if all have correct mimetype and type = file
151
				if(self._ocr.checkMimeTypes(selFiles)){
152
					// show if not already shown
153
					selectedActionButton.removeClass('hidden');
154
				}else{
155
					selectedActionButton.addClass('hidden');
156
				}
157
			}else{
158
				// hide if not already hidden
159
				selectedActionButton.addClass('hidden');
160
				self.setSelectedFiles([]);
161
			}
162
		},
163
		togglePendingState: function (force) {
164
			var self = this;
165
			var html = '';
166
			var pendingcount = self._ocr.getStatus().pending;
167
			if(force){
168
				html = '<span class="icon icon-loading-small"></span>&nbsp;<span>' + t('ocr','OCR processing started.') + '</span>';
169
			}else{
170
				html = '<span class="icon icon-loading-small"></span>&nbsp;<span>' + pendingcount + ' ' + t('ocr','currently pending OCR requests.') + '</span>';
171
			}
172
			if(pendingcount > 0 || force){
173
				if (self._row !== undefined) { OC.Notification.hide(self._row); }
174
				self._row = OC.Notification.showHtml(html);
175
			}else{
176
				if (self._row !== undefined){
177
					OC.Notification.hide(self._row);
178
					self._row = undefined;
179
				}
180
			}
181
		},
182
		updateFileList: function () {
183
			var self = this;
184
			OCA.Files.App.fileList.reload();
185
			self.toggleSelectedActionButton('');
186
		},
187
		/**
188
		 * Loops as long as there are pending objects
189
		 */
190
		loopForStatus: function () {
191
			var self = this;
192
			$.when(self._ocr.checkStatus()).done(function(){
193
				if(self._ocr.getStatus().failed > 0) { self.notifyError('OCR processing for one or more files failed. For details please contact your administrator.'); }
194
				if(self._ocr.getStatus().pending > 0){
195
					if(self._ocr.getStatus().processed > 0) { self.updateFileList(); }
196
					self.togglePendingState(false);
197
					setTimeout($.proxy(self.loopForStatus,self), 4500);
198
				}else{
199
					if(self._ocr.getStatus().processed > 0) self.updateFileList();
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
200
					self.togglePendingState(false);
201
				}
202
			}).fail(function(message){
203
				self.notifyError(message);
204
				setTimeout($.proxy(self.loopForStatus,self), 4500);
205
			});
206
		},
207
		notifyError: function (message) {
208
			/** global: OC */
209
			OC.Notification.showHtml('<div>'+t('ocr', message)+'</div>', {timeout: 10, type: 'error'});
210
		},
211
		registerEvents: function(){
212
			var self = this;
213
			// Close on click on other element
214
			$(document).click(function(event) {
215
				if(!$(event.target).closest('#ocrDropdown').length) {
216
					self.destroyDropdown();
217
					self.setSelectedFiles([]);
218
				}
219
			});
220
			// Register submit action
221
			$(document).on('click', '#processOCR', function(){
222
				var selectedLanguage = $('#ocrLanguage').val();
223
				$.when(self._ocr.process(self.getSelectedFiles(), selectedLanguage)).done(function(){
224
					self.destroyDropdown();
225
					self.setSelectedFiles([]);
226
					// status monitoring init
227
					self.togglePendingState(true);
228
					setTimeout($.proxy(self.loopForStatus,self), 4500);
229
				}).fail(function(message){
230
					self.notifyError('OCR processing failed: ' + message);
231
					self.destroyDropdown();
232
				});
233
			});
234
			// Register click selectedFilesAction
235
			$(document).on('click', '#selectedFilesOCR', function(){
236
				var html = self.renderDropdown();
237
				$(html).appendTo($('tr').find('th.column-name'));
238
				self.setSelectedFiles(OCA.Files.App.fileList.getSelectedFiles());
239
				return false;
240
			});
241
			// Register checkbox events
242
			/** global: _ */
243
			OCA.Files.App.fileList.$fileList.on('change', 'td.filename>.selectCheckBox', _.bind(self.toggleSelectedActionButton, this));
244
			OCA.Files.App.fileList.$el.find('.select-all').click(_.bind(self.toggleSelectedActionButton, this));
245
		}
246
	};
247
	/** global: OCA */
248
	if (OCA.Ocr) {
249
		OCA.Ocr.View = View;
250
	}
251
})();